unit Toppanel;
interface

uses Windows, Messages, SysUtils, Classes, Controls, Forms,
  CommCtrl, StdCtrls, Buttons, ExtCtrls, Graphics, Topframe;

type

  TTopCustomPanel = class(TCustomPanel)
  private
    FFrame: TTopEditFrame;
    FFocused: boolean;
    procedure WMEraseBkGnd(var Message:TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure WMMove(var Message: TWMMove); Message WM_Move;
    procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  protected
    // Property Storage Variables
    FTransparent: Boolean;

    procedure ClipChildren(Value: Boolean);
    procedure CreateWnd; override;

    // Property Access Methods
    procedure SetTransparent(Value: Boolean); virtual;

    // Overridden methods
    procedure Paint; override;
    procedure AlignControls(AControl: TControl; var Rect: TRect); override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure SetParent(AParent:TWinControl); override;
    function IsTransparent: boolean; virtual;
    function InvalidateNeeded:boolean; virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Invalidate; override;

    property Frame: TTopEditFrame read FFrame write FFrame;
    property Transparent: Boolean read FTransparent write SetTransparent default False;
  end;


implementation

uses Topcommon;

constructor TTopCustomPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FFrame:= TTopEditFrame.create(self);
  FTransparent := False;
end;

destructor TTopCustomPanel.Destroy;
begin
  FFrame.Free;
  inherited Destroy;
end;

procedure TTopCustomPanel.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  if IsTransparent then
     Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
end;

procedure TTopCustomPanel.AlignControls(AControl: TControl; var Rect: TRect);
begin
  inherited;
  if IsTransparent then Invalidate;
end;

procedure TTopCustomPanel.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  if IsTransparent then Message.result:=1
  else inherited;
end;

procedure TTopCustomPanel.WMMove(var Message: TWMMove);
begin
  inherited;
  if IsTransparent then Invalidate;
end;

procedure TTopCustomPanel.ClipChildren(Value: Boolean);
//var tc: TWinControl;
begin
  if (Parent <> nil) then
  begin
      SetWindowLong(Parent.Handle, GWL_STYLE,
        GetWindowLong(Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
      if HandleAllocated then
        SetWindowLong(Handle, GWL_STYLE,
          GetWindowLong(Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
//    tc:= self;
//
    // Only disable parent clipping, don't enable it
//    while (tc.parent<>nil) do begin
//        SetWindowLong(tc.Parent.Handle, GWL_STYLE,
//          GetWindowLong(tc.Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
//      if tc.parent is TCustomForm then break;
//      tc:= tc.parent;
//      break;
//    end;
  end
end;

procedure TTopCustomPanel.SetParent(AParent:TWinControl);
begin
  inherited SetParent(AParent);

  // Without this, the panel would be transparent indeed, but you would see through the form into the background apps
//  ClipChildren(not FTransparent);
end;

procedure TTopCustomPanel.Invalidate;
var TempRect:TRect;
    r: TRect;
begin
//  inherited;
//  exit;
  if IsTransparent and (Parent <> nil) and Parent.HandleAllocated then
  begin
    GetUpdateRect(Handle, r, False);
    tempRect:= BoundsRect;
    tempRect:= Rect(TempRect.Left + r.Left, TempRect.Top + r.Top,
                    TempRect.Left + r.Right, TempRect.Top + R.Bottom);
    InvalidateRect(Parent.Handle, @TempRect, False);
   // 10/23/01 - The following code causes a transpareant panel to not be transparent in some cases
   // when the form first comes up.  In fact only 1 panel seems to exhibit this problem
   // when having multiple panels or groupboxes.

{    if not fcIsTransparentParent(self) then
       Parent.Update; // Seems necessary for transparent panel in transparent panel when
}
    if (r.left=r.right) and (r.top=r.bottom) then
      InvalidateRect(Handle, nil, False)
    else InvalidateRect(Handle, @r, False);
  end
  else inherited Invalidate;
end;

procedure TTopCustomPanel.SetTransparent(Value: Boolean);
begin
  if FTransparent <> Value then
  begin
    FTransparent := Value;

    if IsTransparent then ControlStyle := ControlStyle - [csOpaque]
    else begin
       ControlStyle := ControlStyle + [csOpaque];
    end;

    if not (csLoading in ComponentState) and HandleAllocated and
       not (csDesigning in ComponentState) then
    begin
      Invalidate;
      ClipChildren(not Value);
      RecreateWnd;
    end
  end;
end;

Function TTopCustomPanel.IsTransparent: boolean;
begin
   result:= FTransparent and not (csDesigning in ComponentState);
end;

//10/23/2001-Handle refresh of text when caption changes.
procedure TTopCustomPanel.CMTextChanged(var Message: TMessage);
begin
  if (not (csDesigning in ComponentState)) or FTransparent then
  begin
     Frame.RefreshTransparentText(True);
  end;
  inherited;
end;


procedure TTopCustomPanel.Paint;
const
  Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
  Rect: TRect;
  TopColor, BottomColor: TColor;
  FontHeight: Integer;
  Flags: Longint;
  TempRect: TRect;

  procedure AdjustColors(Bevel: TPanelBevel);
  begin
    TopColor := clBtnHighlight;
    if Bevel = bvLowered then TopColor := clBtnShadow;
    BottomColor := clBtnShadow;
    if Bevel = bvLowered then BottomColor := clBtnHighlight;
  end;

begin
  Rect := GetClientRect;

  if Frame.IsFrameEffective then
  begin
     if (Frame.NonFocusColor<>clNone) and (not FFocused) then
        Canvas.Brush.Color := Frame.NonFocusColor
     else Canvas.Brush.Color := Color;
     if not Transparent then Canvas.FillRect(Rect);
     fcDrawEdge(self, Frame, Canvas, FFocused);
  end
  else begin
     if BevelOuter <> bvNone then
     begin
       AdjustColors(BevelOuter);
       Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
     end;
     Frame3D(Canvas, Rect, Color, Color, BorderWidth);
     if BevelInner <> bvNone then
     begin
       AdjustColors(BevelInner);
       Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
     end;
  end;

  with Canvas do
  begin
    if not Transparent then
    begin
       TempRect:= Rect;
       if not Frame.IsFrameEffective then
       begin
          Brush.Color := Color;
          FillRect(TempRect);
       end;
    end;
    Brush.Style := bsClear;
    Font := Self.Font;
    FontHeight := TextHeight('W');
    with Rect do
    begin
      Top := ((Bottom + Top) - FontHeight) div 2;
      Bottom := Top + FontHeight;
    end;
    Flags := DT_EXPANDTABS or DT_VCENTER or Alignments[Alignment];
    Flags := DrawTextBiDiModeFlags(Flags);
    if Frame.IsFrameEffective then
    begin
       if (Frame.NonFocusFontColor<>clNone) and (not FFocused) then
          Font.Color := Frame.NonFocusFontColor
    end;
//    DrawText(Handle, PChar(Caption), -1, Rect, Flags);
  end;
end;




procedure TTopCustomPanel.CreateWnd;
begin
   inherited;
   ClipChildren(not FTransparent);
end;


function TTopCustomPanel.InvalidateNeeded:boolean;
begin
  result := False;
  if Frame.Enabled then
    if (Frame.NonFocusColor <> clNone) then begin
       if (Color <> Frame.NonFocusColor) then result := True;
    end
    else if (Frame.NonFocusFontColor <> clNone) then begin
       if (Font.Color <> Frame.NonFocusFontColor) then result := True;
    end;
end;

procedure TTopCustomPanel.CMEnter(var Message: TCMEnter);
var r,r2:TRect;
begin
   inherited;
   FFocused:= True;
   if invalidateneeded then invalidate;

   if Frame.Enabled then
   if (Frame.FocusBorders * Frame.NonFocusBorders <> Frame.FocusBorders) or
      (Frame.FocusStyle <> Frame.NonFocusStyle) then
   begin
     r:= ClientRect;
     r2:= Rect(r.left+2,r.top+2,r.right-2,r.bottom-2);
     ValidateRect(handle,@r2);
     InvalidateRect(handle, @r, False);
   end;
end;

procedure TTopCustomPanel.CMExit(var Message: TCMExit);
var r,r2:Trect;
begin
   inherited;
   FFocused:= False;
   if invalidateneeded then invalidate;

   if Frame.Enabled then
   if (Frame.FocusBorders * Frame.NonFocusBorders <> Frame.FocusBorders) or
      (Frame.FocusStyle <> Frame.NonFocusStyle) then
   begin
     r:= ClientRect;
     r2:= Rect(r.left+2,r.top+2,r.right-2,r.bottom-2);
     ValidateRect(handle,@r2);
     InvalidateRect(handle, @r, False);
   end;
end;


end.

